	.	=	12130	;ORGIN FOR 4K WITH IOX AT 15100
	.EOT

;   ODT-11X -- V006A

; COPRIGHT 1969,1970, DIGITAL EQUIPMENT CORPORATION

R0	=	%0	; REGISTER
R1	=	%1	;  NAMING
R2	=	%2	;   CONVENTIONS
R3	=	%3
R4	=	%4
R5	=	%5
SP	=	%6
PC	=	%7
ST	=	177776		;STATUS REGISTER
O.TMP	=	.
.	=	42
	.BYTE	006,'A		;VERSION 006A
.	=	O.TMP

O.BKP	=	16		;NUMBER OF BREAKPOINTS-1 MULT. BY 2
O.TVEC	=	14		;TRT VECTOR LOCATION
O.STM	=	340		;PRIORITY MASK - STATUS REGISTER
O.TBT	=	20		;T-BIT MASK - STATUS REGISTER
TRT	=	000003		;TRT INSTRUCTION


O.RDB	=	177562	;R DATA BUFFER
O.RCSR	=	177560	;R C/SR
O.TDB	=	177566	;T DATA BUFFER
O.TCSR	=	177564	;T C/SR


; INITIALIZE ODT
;  USE O.ODT FOR A NORMAL ENTRY
;  USE O.ODT+2 TO RESTART ODT - WIPING OUT ALL BREAKPOINTS
;  USE O.ODT+4 TO RE-ENTER (I.E. - FAKE A BREAKPOINT)

O.ODT:	BR	O.STRT		;NORMAL ENTRY
	BR	O.RST		;RESTART
O.ENTR:	MOV	ST,O.UST	;RE-ENTER -- SAVE STATUS
	MOV	O.TVEC+2,ST	;SET UP LOCAL STATUS
	MOV	PC,O.UPC	;FAKE THE PC
	MOVB	#-1,O.P		;DISALLOW PROCEED
	CLRB	O.S
	JMP	O.BK1

O.STRT:	MOV	#O.UR0,SP	;SET UP STACK
	MOV	SP,O.USP	;FAKE THE SAVED STACK
	BR	O.RST1
O.RST:	JSR	0,O.SVR		;SAVE REGISTERS
	JSR	5,O.REM		;REMOVE ALL BREAKPOINTS
	MOVB	O.PRI,R4	;GET ODT PRIORITY
	RORB	R4		;SHIFT
	RORB	R4		; INTO
	RORB	R4		;  POSITION
	MOVB	R4,ST		;STORE IN STATUS
O.RST1:	CLRB	O.S		;DISABLE SINGLE INSTRUCTION FOR NOW
	MOVB	#-1,O.P		;DISALLOW PROCEED
	MOV	#O.STM,O.TVEC+2	;STATUS WORD TO TRT VECTOR+2
	MOV	#O.BRK,O.TVEC	;PC TO TRT VECTOR
	JMP	O.RALL		;CLEAR BREAKPOINT TABLES


; SPECIAL NAME HANDLER
;  DEPENDS UPON THE EXPLICIT ORDER OF THE TWO TABLES O.TL AND O.UR0

O.REGT:	JSR	5,O.GET		;SPECIAL NAME, GET ONE MORE CHARACTER
	MOV	#O.TL,R4	;TABLE START ADDRESS
O.RSP:	CMPB	R0,(R4)+	;IS THIS THE CORRECT CHARACTER?
	BEQ	O.SP		;JUMP IF YES
	CMP	#O.TL+O.LG,R4	;IS THE SEARCH DONE?
	BHI	O.RSP		;BRANCH IF NOT
	BIC	#177770,R0	;MASK OFF OCTAL
	MOV	R0,R4
O.SP1:	ASL	R4
	ADD	#O.UR0,R4	;GENERATE ADDRESS
	INC	R2		;SET FOUND FLAG
	BR	O.SCAN		;GO FIND NEXT CHARACTER
O.SP:	SUB	#O.TL-7,R4	;GO FIND NEXT CHARACTER
	BR	O.SP1

; _ HANDLER - OPEN INDEXED ON THE PC

O.ORPC:	JSR	5,O.TCLS	;TEST WORD MODE AND CLOSE
	ADD	@R2,R2		;COMPUTE
	INC	R2
	INC	R2		;   NEW ADDRESS
O.PCS:	MOV	R2,O.CAD	;UPDATE CAD
	JMP	O.OP2A		;GO FINISH UP
O.ORAB:	JSR	5,O.TCLS		;TEST WORD MODE AND CLOSE
	MOV	@R2,R2		;GET ABSOLUTE ADDRESS
	BR	O.PCS
O.ORRB:	JSR	5,O.TCLS	;TEST AND CLOSE
	MOV	@R2,R1		;COMPUTE NEW ADDRESS
	MOVB	R1,R1		;EXTEND THE SIGN
	ASL	R1		;R2=2(@R2)
	INC	R1		;   +2
	INC	R1
	ADD	R1,R2		;   +PC
	BR	O.PCS
O.TCLS:	JSR	PC,O.CLSE	;CLOSE CURRENT CELL
	CMP	#2,O.BW		;ONLY WORD MODE ALLOWED
	BNE	O.TCL1		;BRANCH IF ERROR
	MOV	O.CAD,R2	;CURRENT ADDRESS IN R2
	RTS	R5
O.TCL1:	TST	(SP)+
	BR	O.ERR		;POP A WORD AND SHOW THE ERROR

;	PROCESS S - SINGLE INSTRUCTION MODE

O.SNGL:	TST	R2		;SEE IF TURN ON OR TURN OFF
	BNE	O.SI1		;BRANCH IF TURNING IT ON
	CLRB	O.S		;CLEAR THE FLAG
	BR	O.DCD		;CONTINUE THE SCAN
O.SI1:	MOVB	#-1,O.S	;SET THE FLAG
	BR	O.DCD
; COMMAND DECODER - ODT11X

;  ALL REGISTERS MAY BE USED (R0-R5),

O.ERR:	MOV	#'?,R0		;  ? TO BE TYPED
	JSR	5,O.FTYP	; OUTPUT ?
O.DCD:	CLR	O.BW		;CLOSE ALL
	JSR	5,O.CRLS	;TYPE  <CR><LF>*
O.DCD2:	CLR	R3		;R3 IS A SAVE REGISTER FOR R2
	CLR	R5		;R5 IS A SAVE REGISTER FOR R4
O.DCD1:	CLR	R4		; R4 CONTAINS THE CONVERTED OCTAL
	CLR	R2		; R2 IS THE NUMBER FOUND FLAG
O.SCAN:	JSR	5,O.GET		;GET A CHAR, RETURN IN R0
	CMP	#'0,R0		;COMPARE WITH ASCII 0
	BHI	O.CLGL		;CHECK LEGALITY IF NON-NUMERIC
	CMP	#'7,R0		;COMPARE WITH ASCII 7
	BLO	O.CLGL		;CHECK LEGALITY IF NOT OCTAL
	BIC	#177770,R0	;CONVERT TO BCD
	ASL	R4		; MAKE ROOM
	ASL	R4		;  IN
	ASL	R4		;    R4
	ADD	R0,R4		;PACK THREE BITS IN R4
	INC	R2		;R2 HAS NUMERIC FLAG
	BR	O.SCAN		;   AND TRY AGAIN
O.CLGL:	CLR	R1		;CLEAR INDEX
O.LGL1:	CMPB	R0,O.LGCH(R1)	;DO THE CODES MATCH?
	BEQ	O.LGL2		;JUMP IF YES
	INC	R1		; SET INDEX FOR NEXT SEARCH
	CMP	R1,#O.CLGT	;IS THE SEARCH DONE?
	BHIS	O.ERR		;    OOPS!
	BR	O.LGL1		;RE-LOOP
O.LGL2:	ASL	R1		;MULTIPLY BY TWO
	JMP	@O.LGDR(R1)	;GO TO PROPER ROUTINE

O.LGDR:	O.SEMI	;  
	O.WRD	;  /    OPEN WORD
	O.BYT	;  \    OPEN BYTE
	O.CRET	;  CARRIAGE RETURN    CLOSE
	O.REGT	;  $  REGISTER OPS
	O.GO	;  G  GO TO ADDRESS K
	O.OP1	;  <LF>  MODIFY, CLOSE, OPEN NEXT
	O.ORPC	;  _  OPEN RELATED, INDEX - PC
	O.OLD	;  <  RETURN TO OLD SEQUENCE AND OPEN
	O.BACK	;  ^  OPEN PREVIOUS
	O.OFST	;  O  OFFSET
	O.WSCH	;  W  SEARCH WORD
	O.EFF	;  E  SEARCH EFFECTIVE ADDRESS
	O.BKPT	;  B  BREAKPOINTS
	O.PROC	;  P  PROCEED
	O.ORAB	;  @  OPEN RELATED, ABSOLUTE
	O.ORRB	;  >  OPEN RELATED, REL. BRANCH
	O.SNGL	;  S  SINGLE INSTRUCTION MODE
O.LGL	=	.-O.LGDR	;LGL MUST EQUAL 2X CHLGT ALWAYS

; SEMI-COLON PROCESSOR

O.SEMI:	MOV	R2,R3	;A SEMI-COLON HAS BEEN RECEIVED
	MOV	R4,R5	;NUMERIC FLAG TO R3, CONTENTS TO R5
	BR	O.DCD1		;GO BACK FOR MORE

; PROCESS / AND \ - OPEN WORD OR BYTE

O.WRD:	MOV	#2,O.BW		;OPEN WORD
	BR	O.WB1
O.BYT1:	ROL	R4		;GET THE ADDRESS BACK
O.BYT:	MOV	#1,O.BW		;OPEN BYTE
O.WB1:	TST	R2		;GET VALUE IF R2 IS NON-ZERO
	BEQ	O.WRD1		;SKIP OTHERWISE
	MOV	R4,O.DOT	;PUT VALUE IN DOT
	MOV	R4,O.CAD	;    ALSO IN CAD
O.WRD1:	CMP	#1,O.BW		;CHECK BYTE MODE
	BEQ	O.WRD2		;JUMP IF BYTE
	MOV	O.CAD,R4
	ASR	R4		;MOVE ONE BIT TO CARRY
	BCS	O.BYT1		;JUMP IF ODD ADDRESS
	MOV	@O.CAD,R0	;GET CONTENTS OF WORD
	BR	O.WRD3
O.WRD2:	MOVB	@O.CAD,R0	;GET CONTENTS OF BYTE
O.WRD3:	JSR	5,O.CADV	;GO GET AND TYPE OUT @CAD
	BR	O.DCD2		;GO BACK TO DECODER

; PROCESS CARRIAGE RETURN

O.CRET:	JSR	PC,O.CLSE	;CLOSE LOCATION
O.DCDA:	BR	O.DCD		;RETURN TO DECODER

; PROCESS <LF>, OPEN NEXT WORD

O.OLD:	INCB	O.SEQ		;SET NEED O.DOT TO O.CAD MOVE
O.OP1:	TST	O.BW		;<LF> RECEIVED
O.ERR2:	BEQ	O.ERR		;ERROR IF NOTHING IS OPEN
	JSR	PC,O.CLSE	;CLOSE PRESENT CELL
	TSTB	O.SEQ		;SEE IF < COMMAND
	BEQ	O.OP5		;BRANCH IF NOT
	MOV	O.DOT,O.CAD	;GO TO THE FORRMER STREAM
O.OP5:	CLRB	O.SEQ		;CLEAR THE FLAG
	ADD	O.BW,O.CAD	;GENERATE NEW ADDRESS
O.OP2:	MOV	O.CAD,O.DOT	;INITIALIZE DOT
O.OP2A:	JSR	5,O.CRLF	;<CR><LF>
	MOV	O.BW,-(SP)	;SAVE BW
	MOV	#2,O.BW		;SET TO TYPE FULL WORD ADDRESS
	MOV	O.CAD,R0	;NUMBER TO TYPE
	JSR	5,O.CADV	; TYPE OUT ADDRESS
	MOV	@SP,O.BW	;RESTORE BW
	CMP	#1,(SP)+	;IS IT BYTE MODE?
	BEQ	O.OP3		;JUMP IF YES
	MOV	#'/,R0		;TYPE A /
O.OP4:	JSR	5,O.FTYP
	BR	O.WRD1		;GO PROCESS IT
O.OP3:	MOV	#'\,R0		;TYPE A \
	BR	O.OP4

; PROCESS ^, OPEN PREVIOUS WORD

O.BACK:	TST	O.BW		;  ^ RECEIVED
	BEQ	O.ERR2		;ERROR IF NOTHING OPEN
	JSR	PC,O.CLSE
	SUB	O.BW,O.CAD	;GENERATE NEW ADDRESS
	BR	O.OP2		;GO DO THE REST

; B HANDLER - SET AND REMOVE BREAKPOINTS

O.BKPT:	MOV	#O.TRTC,R0
	ASL	R4		;MULTIPLY NUMBER BY TWO
	TST	R3
	BEQ	O.REMB		;IF R3 IS ZERO GO REMOVE BREAKPOINT
	ASR	R5		;GET ONE BIT TO CARRY
	BCS	O.ERR1		;BADNESS IF ODD ADDRESS
	ASL	R5		;RESTORE ONE BIT
	ADD	#O.ADR1,R4
	TST	R2
	BNE	O.SET1		;JUMP IF SPECIFIC CELL
O.SET:	CMP	R0,@R4		;IS THIS CELL FREE?
	BEQ	O.SET1		;JUMP IF YES
	CMP	R4,#O.BKP+O.ADR1	;ARE WE AT THE END OF OUR ROPE
	BHIS	O.ERR1		;YES, THERE IS NOTHING FREE
	TST	(R4)+		;INCREMENT BY TWO
	BR	O.SET
O.SET1:	CMP	R4,#O.BKP+O.ADR1
	BHI	O.ERR1		;ERROR IF TOO LARGE
	MOV	R5,@R4		;SET BREAKPOINT
	BR	O.DCDA		;RETURN
O.REMB:	TST	R2
	BEQ	O.RALL		;GO REMOVE ALL
	CMP	R4,#O.BKP
	BHI	O.ERR1		;JUMP IF NUMBER TOO LARGE
	MOV	R0,O.ADR1(R4)	;CLEAR BREAKPOINT
	CLR	O.CT(R4)	;CLEAR COUNT ALSO
O.DCDB:	BR	O.DCDA
O.RALL:	CLR	R4
	MOV	#O.TRTC,R0
O.RM1:	CMP	R4,#O.BKP+2	;ALL DONE?
	BHI	O.DCDA		;JUMP IF YES
	MOV	R0,O.ADR1(R4)	;RESET BKPT
	MOV	#TRT,O.UIN(R4)	;RESET CONTENTS OF TABLE
	CLR	O.CT(R4)	;CLEAR COUNT
	TST	(R4)+		;INCREMENT BY TWO
	BR	O.RM1

; PROCESS O, COMPUTE OFFSET

O.OFST:	CMP	#2,O.BW		;CHECK WORD MODE
	BNE	O.ERR1		;ERROR IF NOT CORRECT MODE
	MOV	#' ,R0		;TYPE ONE BLANK
	JSR	5,O.FTYP	;  AS A SEPARATOR
	TST	R3		;WAS SEMI-COLON TYPED?
	BEQ	O.ERR1		;NO, CALL IT AN ERROR
O.OF2:	SUB	O.CAD,R5	;COMPUTE
	DEC	R5
	DEC	R5		;    16 BIT OFFSET
	MOV	R5,R0
	JSR	5,O.CADV	;NUMBER IN R0 - WORD MODE
	MOV	R5,R0
	ASR	R0		;DIVIDE BY TWO
	BCS	O.OF1		;ERROR IF ODD
	CMP	#-200,R0	;COMPARE WITH -200
	BGT	O.OF1		;DO NOT TYPE IF OUT OF RANGE
	CMP	#177,R0		;COMPARE WITH +177
	BLT	O.OF1		;DO NOT TYPE IF OUT OF RANGE
	DEC	O.BW		;SET TEMPORARY BYTE MODE
	JSR	5,O.CADV	;NUMBER IN R0 - BYTE MODE
	INC	O.BW		;RESTORE WORD MODE
O.OF1:	JMP	O.DCD2		;ALL DONE

O.ERR1:	JMP	O.ERR		;INTERMEDIATE HELP

; SEARCHES - $MSK   HAS THE MASK
;		$MSK+2 HAS THE FWA
;		$MSK+4 HAS THE LWA

O.EFF:	INC	R1		;SET EFFECTIVE SEARCH
	BR	O.WDS
O.WSCH:	CLR	R1		;SET WORD SEARCH
O.WDS:	TST	R3		;CHECK FOR OBJECT FOUND
	BEQ	O.ERR1		;ERROR IF NO OBJECT
	MOV	#2,O.BW		;SET WORD MODE
	MOV	O.MSK+2,R2	;SET ORIGIN
	MOV	O.MSK,R4	;SET MASK
	COM	R4
O.WDS2:	CMP	R2,O.MSK+4	; IS THE SEARCH ALL DONE?
	BHI	O.DCDB		;  YES
	MOV	@R2,R0		; GET OBJECT
	TST	R1		;NO
	BNE	O.EFF1		;BRANCH IF EFFECTIVE SEARCH
	MOV	R0,-(SP)
	MOV	R5,R3		;EXCLUSIVE OR
	BIC	R5,R0		; IS DONE
	BIC	(SP)+,R3		;  IN A VERY
	BIS	R0,R3		;    FANCY MANNER HERE
	BIC	R4,R3		;AND RESULT WITH MASK
O.WDS3:	BNE	O.WDS4		;RE-LOOP IF NO MATCH
	MOV	R4,-(SP)	;REGISTERS R2,R4, AND R5 ARE SAFE
	JSR	5,O.CRLF
	MOV	R2,R0		;GET READY TO TYPE
	JSR	5,O.CADV	;  TYPE ADDRESS
	MOV	#'/,R0		;SLASH TO R0
	JSR	5,O.FTYP	;TYPE IT
	MOV	@R2,R0		;GET CONTENTS
	JSR	5,O.CADV	;TYPE CONTENTS
	MOV	(SP)+,R4	; RESTORE R4
O.WDS4:	TST	(R2)+		;INCREMENT TO NEXT CELL AND
	BR	O.WDS2		;    RETURN
O.EFF1:	CMP	R0,R5		; IS (X)=K?
	BEQ	O.WDS3		;TYPE IF EQUAL
	MOV	R0,R3		;(X) TO R3
	ADD	R2,R3		;(X)+X
	INC	R3
	INC	R3		;(X)+X+2
	CMP	R3,R5		;IS (X)+X+2=K?
	BEQ	O.WDS3		;BRANCH IF EQUAL
	BIC	#177400,R0	;WIPE OUT EXTRANEOUS BITS
	MOVB	R0,R0
	CCC
	ASL	R0		;MULTIPLY BY TWO
	INC	R0
	INC	R0
	ADD	R2,R0		;ADD PC
	CMP	R0,R5		;IS THE RESULT A PROPER REL. BRANCH?
	BR	O.WDS3

; PROCESS G - GO

O.GO:	TST	R3		;WAS K; TYPED?
	BEQ	O.ERR1		; TYPE ?<CR,LF> IF NOT
	MOVB	#O.BKP+3,O.P	;CLEAR PROCEED
	ASR	R5		;CHECK LOW ORDER BIT
	BCS	O.ERR1		;ERROR IF ODD NUMBER
	ASL	R5		;RESTORE WORD
	MOV	R5,O.UPC	;SET UP NEW PC
	MOVB	#O.STM,ST		;SET HIGH PRIORITY
	JSR	5,O.RSTT	;RESTORE TELETYPE
O.TBIT:	CLRB	O.T		;CLEAR
	BIS	#O.TBT,O.UST	;    BOTH T-BIT FLAGS
	TSTB	O.S		;SEE IF WE NEED A T BIT
	BNE	O.GO2		;IF NOT GO NOW
	BIC	#O.TBT,O.UST	;SET TH T BIT
O.GO1:	JSR	5,O.RSB		;RESTORE BREAKPOINTS
O.GO2:	JSR	0,O.RSR		;RESTORE REGISTERS
	MOV	O.UST,-(SP)	;    AND STATUS
	MOV	O.UPC,-(SP)	;    AND PC
	RTI

; PROCESS P - PROCEED 
;   ONLY ALLOWED AFTER A BREAKPOINT

O.PROC:	MOVB	O.P,R0
	TSTB	R0		;CHECK LEGALITY OF PROCEED
	BLT	O.ERR1		;NOT LEGAL
	TST	R2		;CHECK FOR ILLEGAL COUNT
	BNE	O.ERR1		;JUMP IF ILLEGAL
	TST	R3		;WAS COUNT SPECIFIED?
	BEQ	O.PR1		;NO
	MOV	R5,O.CT(R0)	;YES, PUT AWAY COUNT
O.PR1:	MOVB	#O.STM,ST	;FORCE HIGH PRIORITY
	JSR	5,O.RSTT	;RESTORE TTY
O.C1:	CMPB	O.P,#O.BKP	;SEE IF A REAL ONE OR A FAKE
	BGT	O.TBIT		;BRANCH IF FAKE
	TSTB	O.S		;SEE IF SINGLE INSTRUCTION MODE
	BNE	O.TBIT		;IF SO EXIT NOW
	MOVB	#O.STM,ST	;SET HIGH PRIORITY
	INCB	O.T		;SET T-BIT FLAG
	BIS	#O.TBT,O.UST	;SET T-BIT
	BR	O.GO2

; BREAKPOINT HANDLER
O.BRK:	MOV	(SP)+,O.UPC	;PRIORITY IS 7 UPON ENTRY
	MOV	(SP)+,O.UST	;SAVE STATUS AND PC
	MOVB	#O.BKP+3,O.P	;TELL ;P THAT WE CAN CONTINUE
O.BK1:	JSR	0,O.SVR		;SAVE VARIOUS REGISTERS
	TSTB	O.T		;CHECK FOR T-BIT SET
	BNE	O.TBIT		;JUMP IF SET
	JSR	5,O.REM		;REMOVE BREAKPOINTS
	TSTB	O.PRI		;CHECK IF PRIORITY
	BPL	O.BK2		; IS AS SAME AS USER PGM
	MOVB	O.UST,R5	;PICK UP USER UST IF SO
	BR	O.BK3
O.BK2:	MOVB	O.PRI,R5	;OTHERWISE PICK UP ACTUAL PRIORITY
	CCC			;CLEAR CARRY
	RORB	R5		;SHIFT LOW ORDER BITS
	RORB	R5		;  INTO
	RORB	R5		;    HIGH ORDER
	RORB	R5		;      POSITION
O.BK3:	MOVB	R5,ST		;PUT THE STATUS AWAY WHERE IT BELONGS
	MOV	O.UPC,R5	;GET PC, IT POINTS TO THE TRT
	TSTB	O.S		;SEE IF IT WAS SINGLE INSTRUCTION FUN
	BMI	O.B4		;IF SO HANDLE THERE
	TST	-(R5)
	MOV	R5,O.UPC
	MOV	#O.BKP,R4	;GET A COUNTER
O.B1:	CMP	R5,O.ADR1(R4)	;COMPARE WITH LIST
	BEQ	O.B2		;JUMP IF FOUND
	DEC	R4
	DEC	R4
	BGE	O.B1		;RE-LOOP UNTIL FOUND
	JSR	5,O.SVTT	;SAVE TELETYPE STATUS
	JSR	5,O.CRLF
	MOV	#O.BD,R4	;ERROR, NOTHING FOUND
	MOV	#O.BD+1,R3
	JSR	5,O.TYPE	;OUTPUT "BE" FOR BAD ENTRY
	MOV	R5,R0
	ADD	#2,O.UPC	;POP OVER THE ADJUSTMENT ABOVE
	BR	O.B3		; OR CONTINUE
O.B4:	MOVB	#O.BKP+2,R4	;SET BREAK POINT HIGH + 1
	MOV	R5,O.ADR1(R4)	;STORE NEXT PC VALUE FOR TYPE OUT
	BR	O.B2
O.B2:	MOVB	R4,O.P		;ALLOW PROCEED
	DEC	O.CT(R4)
	BGT	O.C1		;JUMP IF REPEAT
	MOV	#1,O.CT(R4)	;RESET COUNT TO 1
	JSR	5,O.SVTT	;SAVE TELETYPE STATUS, R4 IS SAFE
	MOV	#'B,R0
	JSR	5,O.FTYP	;TYPE "B"
	MOVB	O.P,R0		;CONVERT BREAKPOINT NUMBER TO ASCII
	ADD	#140,R0
	ASR	R0
	JSR	5,O.FTYP
	MOV	#';,R0
	JSR	5,O.FTYP	; TYPE 
	MOV	#2,O.BW		; SET WORD MODE
	MOVB	O.P,R4
	MOV	O.ADR1(R4),R0	;GET ADDRESS OF BREAK
O.B3:	JSR	5,O.CADV	;TYPE ADDRESS
	JMP	O.DCD		;GO TO DECODER
; SAVE REGISTERS R0-R6
;   INTERNAL STACK

O.SVR:	MOV	(SP)+,O.XXX	;PICK REGISTER FROM STACK AND SAVE
	MOV	SP,O.USP	;SAVE USER STACK ADDRESS
	MOV	#O.USP,SP	;SET TO INTERNAL STACK
	MOV	R5,-(SP)	;SAVE
	MOV	R4,-(SP)	; REGISTERS
	MOV	R3,-(SP)	;1
	MOV	R2,-(SP)	; THRU
	MOV	R1,-(SP)	;     5
	MOV	O.XXX,-(SP)	;PUT SAVED REGISTER ON STACK
	TST	-(SP)
	RTS	R0

; RESTORE REGISTERS R0-R6

O.RSR:	TST	(SP)+		;POP THE EXTRA CELL
	MOV	(SP)+,O.XXX	;GET R0 FROM STACK
	MOV	(SP)+,R1	;RESTORE
	MOV	(SP)+,R2	; REGISTERS
	MOV	(SP)+,R3	;  1
	MOV	(SP)+,R4	;  THRU
	MOV	(SP)+,R5	;    5
	MOV	O.USP,SP	;RESTORE USER STACK
	MOV	O.XXX,-(SP)	;PUT R0 ON USER STACK
	RTS	R0

; RESTORE BREAKPOINTS 0-7

O.RSB:	MOV	#O.BKP,R4	;RESTORE ALL BREAKPOINTS
O.RS1:	MOV	@O.ADR1(R4),O.UIN(R4)	;SAVE CONTENTS
	MOV	O.TRTC,@O.ADR1(R4)	;REPLACE WITH TRAP
	DEC	R4
	DEC	R4
	BGE	O.RS1		;RE-LOOP UNTIL DONE
	RTS	R5		;  THEN QUIT

; SAVE TELETYPE STATUS

O.SVTT:	MOVB	O.RCSR,O.CSR1	;SAVE R C/SR
	MOVB	O.TCSR,O.CSR2	;SAVE T C/SR
	CLRB	O.RCSR		;CLEAR ENABLE AND MAINTENANCE
	CLRB	O.TCSR		;  BITS IN BOTH C/SR
	RTS	R5

; RESTORE TELETYPE STATUS

O.RSTT:	JSR	5,O.CRLF
	TSTB	O.TCSR		;WAIT READY
	BPL	.-4		;  ON PRINTER
	BIT	#4000,O.RCSR	;CHECK BUSY FLAG
	BEQ	O.RSE1		;SKIP READY LOOP IF NOT BUSY
	TSTB	O.RCSR		;WAIT READY
	BPL	.-4		;    ON READER
O.RSE1:	MOVB	O.CSR1,O.RCSR	;RESTORE
	MOVB	O.CSR2,O.TCSR	;  THE STATUS REGISTERS
	RTS	R5

; REMOVE BREAKPOINTS 0-7
;   IN THE OPPOSITE ORDER OF SETTING

O.REM:	TSTB	O.S		;SEE IF SINGLE INSTRUCTION IS GOING
	BNE	O.R2		;EXIT IF SO
	CLR	R4		;REMOVE ALL BREAKPOINTS
O.R1:	MOV	O.UIN(R4),@O.ADR1(R4)	;CLEAR BREAKPOINT
	INC	R4
	INC	R4
	CMP	R4,#O.BKP
	BLE	O.R1		;RE-LOOP UNTIL DONE
O.R2:	RTS	R5		;THEN QUIT

; TYPE OUT CONTENTS OF WORD OR BYTE WITH ONE TRAILING SPACE
; WORD IS IN R0

O.CADV:	MOV	#6,R3		;# OF DIGITS
	MOV	#-2,R4		;# OF BITS FIRST-3
	CMP	#1,O.BW		;SEE IF WORD MODE
	BNE	O.SPC		;BRANCH IF SO
	SUB	#3,R3		;ONLY DO 3 DIGITS
	INC	R4		;DO 2 BITS FIRST
	SWAB	R0		;AND TURN R0 AROUND
O.SPC:	MOV	R0,-(SP)	;SAVE R0
O.V0:	ADD	#3,R4		;COMPUTE THE NUMBER OF BITS TO DO
	CLR	R0
O.V1:	ROL	(SP)		;GET A BIT
	ROL	R0		;STORE IT AWAY
	DEC	R4		;DECREMENT COUNTER
	BGT	O.V1		;LOOP IF MORE BITS NEEDED
	ADD	#'0,R0		;CONVERT TO ASCII
	JSR	R5,O.FTYP	;TYPE IT
	DEC	R3		;SEE IF MORE DIGITS TO DO
	BGT	O.V0		;LOOP IF SO
	MOVB	#' ,R0		;SET UP FOR TRAILING SPACE
	TST	(SP)+		;GET RID OF JUNK AND FALL THRU TO FTYP

; TYPE ONLY ONE CHARACTER (CONTAINED IN R0)

O.FTYP:	TSTB	O.TCSR
	BPL	.-4
	MOVB	R0,O.TDB
O.TYP1:	RTS	R5
; GENERAL CHARACTER INPUT ROUTINE -- ODT11X
; CHARACTER INPUT GOES TO R0

O.GET:	TSTB	O.RCSR		;WAIT FOR
	BPL	.-4		;  INPUT FROM KBD
	MOVB	O.RDB,R0	;GET CHARACTER - STRIP OFF PARITY
	BIC	#177600,R0	;STRIP OFF PARITY FROM CHARACTER
	CMPB	R0,#012		;SEE IF A <LF>
	BEQ	O.GET1		;IF SO SAVE THE PAPER
	JSR	5,O.FTYP	;ECHO CHARACTER
	BEQ	O.GET		;IGNORE NULLS
	CMPB	#40,R0		;CHECK FOR SPACES
	BEQ	O.GET		;IGNORE SPACES
O.GET1:	RTS	R5

; GENERAL CHARACTER OUTPUT ROUTINE - ODT11X
;  ADDRESS OF FIRST BYTE IN R4,
;  ADDRESS OF LAST BYTE IN R3, (R3)>(R4)

O.TYPE:	CMP	R3,R4		;CHECK FOR COMPLETION
	BLO	O.TYP1		; EXIT WHEN DONE
	MOVB	(R4)+,R0	;GET A CHARACTER
	JSR	5,O.FTYP	;TYPE ONE CHARACTER
	BR	O.TYPE		;LOOP UNTIL DONE

; CLOSE WORD OR BYTE AND EXIT,
; UPON ENTERING, R2 HAS NUMERIC FLAG, R4 HAS CONTENTS

O.CLSE:	TST	R2		;IF NO NUMBER WAS TYPED THERE IS
	BEQ	O.CLS1		;NO CHANGE TO THE OPEN CELL
	CMP	#1,O.BW
	BEQ	O.CLS2		;JUMP IF BYTE MODE
	BHI	O.CLS1		;JUMP IF ALREADY CLOSED
	MOV	R4,@O.CAD	;STORE WORD
	BR	O.CLS1
O.CLS2:	MOVB	R4,@O.CAD	;STORE BYTE
O.CLS1:	RTS	PC

O.CRLF:	MOV	#O.CR+1,R3	;LWA <CR,LF>
	BR	O.CRS
O.CRLS:	MOV	#O.CR+2,R3	;LWA <CR,LF>*
O.CRS:	MOV	#O.CR,R4	;FWA
	JSR	5,O.TYPE	;TYPE SOMETHING
	RTS	R5

O.BW:	0			; =0 - ALL CLOSED,
				; =1 - BYTE OPEN,
				; =2 - WORD OPEN
O.CAD:	0			; CURRENT ADDRESS
O.DOT:	0			; ORIGIN ADDRESS
O.XXX:	.WORD	0		;TEMPORARY STORAGE
O.WDFG:	.BYTE	0		;SEARCH FLAG = 1 - EFFECTIVE
				;            = 0 - WORD
O.S:	.BYTE	0		;SINGLE INSTRUCTION FLAG
				;0 IF NOT ACTIVE
				;-1 IF ACTIVE
				;NO BREAK BOINTS MAY BE SET WHILE IN 
				;SINGLE INSTRUCTION MODE
O.T:	.BYTE	0		;  T-BIT FLAG
O.P:	.BYTE	0		;PROCEED FLAG = -2 IF MANUAL ENTRY
				;		-1 IF NO PROCEED ALLOWED
				;		0-7 IF PCEED ALLOWED
O.CSR1:	.BYTE	0		;SAVE CELL - R C/SR
O.CSR2:	.BYTE	0		;SAVE CELL - T C/SR
O.SEQ:	.BYTE	0		;FLAG FOR < COMMAND

	.EVEN
O.BD:	.WORD	"BE

O.CR:	.BYTE	015	;  <CR>
	.BYTE	012	;  <LF>
	.BYTE	'*	;  *

O.LGCH:	.BYTE	';	;  
	.BYTE	'/	;  /
	.BYTE	'\	;  \
	.BYTE	015	;  CARRIAGE RETURN
	.BYTE	'$	;  $
	.BYTE	'G	;  G
	.BYTE	012	;  <LF>
	.BYTE	'_	;  _
	.BYTE	'<	;  <
	.BYTE	'^	;  ^
	.BYTE	'O	;  O
	.BYTE	'W	;  W
	.BYTE	'E	;  E
	.BYTE	'B	;  B
	.BYTE	'P	;  P
	.BYTE	'@	;  @
	.BYTE	'>	;  >
	.BYTE	'S	;  S
O.CLGT	=	.-O.LGCH		;TABLE LENGTH

O.TL:	.BYTE	'S	;DO	  1
	.BYTE	'P	;NOT	  2
	.BYTE	'M	;CHANGE	  3
	.BYTE	0	;THE	  4
	.BYTE	0	;ORDER	  5
	.BYTE	'B	;HERE	  6
O.LG	=	.-O.TL
	.EVEN
O.TRTC:	TRT			;TRACE TRAP PROTOTYPE

;THE ORDER OF THE FOLLOWING ENTRIES IS CRITICAL

.	=	O.ODT-120	;ODT'S STACK IMMEDIATELY PRECEDES ODT

O.UR0:	0	;USER R0
	0	;     R1
	0	;     R2
	0	;     R3
	0	;     R4
	0	;     R5
O.USP:	0	;USER SP
O.UPC:	0	;USER PC
O.UST:	0	;USER ST
O.PRI:	7	;ODT PRIORITY
O.MSK:	0	;MASK
	0	;LOW LIMIT
	0	;HIGH LIMIT

; BREAK POINT LISTS, ADR1 = ADDRESS OF BREAKPOINT,CT = COUNT,
;   UIN = CONTENTS

O.ADR1:	
.	=	.+O.BKP+4
O.CT:	
.	=	.+O.BKP+4
O.UIN:	
.	=	.+O.BKP+4
	.EOT
	.END	O.ODT
 